#include <thread>
#include <stdx/all.h>


class DaemonApplication : public Application
{
protected:
	string cmd;

public:
	void run()
	{
		if (System(cmd.c_str()) < 0)
		{
			fprintf(stderr, "execute command[%s] failed\n", cmd.c_str());
		}
	}
	bool loop()
	{
		string name;
		Sharemem shm;

		stdx::format(name, "DAEMON{%d}", (int)Process::GetCurrentProcess());

		if (shm.create(name))
		{
			CHECK_FALSE_RETURN(Process::SetEnv(DAEMON_ENVNAME, name));

			const char* cmd = (char*)(shm.get());

			while (true)
			{
				run();

				sleep(1);

				CHECK_FALSE_RETURN(strcmp(cmd, "restart") == 0);
			}
		}

		return true;
	}
	bool main()
	{
#ifdef XG_LINUX
		Process::InitDaemon();
#else
		string key = "{daemoncommand}";
		string tmp = Process::GetEnv(key);

		if (tmp.empty())
		{
			int flag = 0;
			string exepath;

			CHECK_FALSE_RETURN(Process::SetEnv(key, cmd));
			CHECK_FALSE_RETURN(Process::GetProcessExePath(exepath));

			exepath = stdx::quote(exepath) +  " " + cmd;

			std::thread([&](){
				flag = 1;
				System(exepath.c_str());
			}).detach();

			while (flag == 0) sleep(1);

			sleep(1);

			return true;
		}

		cmd = tmp;
#endif
		return loop();
	}
	DaemonApplication()
	{
		int cnt = GetCmdParamCount();
		const char* path = GetCmdParam(1);

		if (cnt < 2 || NULL == path || 0 == *path)
		{
			puts("please input executable command");

			SystemExit(0);
		}
		
		cmd = stdx::quote(path);
		
		for (int i = 2; i < cnt; i++)
		{
			cmd += " " + stdx::quote(GetCmdParam(i));
		}
	}
};

START_APP(DaemonApplication)